1 Libraries


  library(package = "tidyverse")
  library(package = "lubridate")

  library(package = "rlist")
  
  library(package = "ncdf4")
  library(package = "ncdf4.helpers")
  
  library(package = "PCICt")
  
  library(package = "reshape2")

2 Input Data File


# directory/URL root

  directory = "/projects/BIG_WEATHER/GENS_ERROR_RT/triangle_archives/"
  directory = "http://kyrill.ias.sdsmt.edu:8080/thredds/fileServer/BWW_GENS/CI_STAT/"

  time_range = "2015-06-01_00_to_2019-03-31_00"
  
  region = "WRFRAP"
  
  RdataFile = str_c(directory,
                  "gens_03_ensemble__",
                  "T2M_MSLP_M10_SPCH2M_ISOHGT_U10_V10_FRICV_GUST",
                  "__error__",
                  region,
                  "__",
                  time_range,
                  ".RData",
                  sep = "")

  load(file = url(RdataFile)) 
  
  Time     = unique(CI_Ensemble_Stats$Time)
  Fx_Hour  = unique(CI_Ensemble_Stats$Fx_Hour)
  Variable = unique(CI_Ensemble_Stats$Variable)
  Height   = unique(CI_Ensemble_Stats$Height)
  
  CI_Ensemble_Stats$Month   = month(CI_Ensemble_Stats$Time)

  CI_Ensemble_Stats = CI_Ensemble_Stats %>% 
    mutate(Quarter = case_when(((Month == 12) | (Month == 01) | (Month == 02))  
                               ~ "DJF",
                               ((Month == 03) | (Month == 04) | (Month == 05))
                               ~ "MAM",
                               ((Month == 06) | (Month == 07) | (Month == 08))
                               ~ "JJA",
                               ((Month == 09) | (Month == 10) | (Month == 11))
                               ~ "SON") )

3 Triangle Plots

3a 2-m Air Temperature


  Var     = "T2M"
  Varname = "2-m Air Temperature"
  Hgt     = 2
  Fx      = 24

  for (Fx in Fx_Hour[2:length(Fx_Hour)]) {
    
    fx_subset = CI_Ensemble_Stats %>% filter((Variable == Var) &
                                             (Height   == Hgt) &
                                             (Fx_Hour  == Fx)  ) %>%
                                      select(-Quarter)
    
    seasonal_subset = CI_Ensemble_Stats %>% filter((Variable == Var) &
                                                   (Height   == Hgt) &
                                                   (Fx_Hour  == Fx)  )
    
    myplot = ggplot(data = seasonal_subset) +
      
      aes(x       = Ens_StDev,
          y       = RMSE_Ens000,
          color   = Quarter) + 
      
      facet_wrap(facets = ~ Quarter) + 
      
      theme_bw() +
      
      theme(strip.background = element_rect(fill=NA),
            ) +
      
      labs(title    = str_c(Fx,
                            "-hr Forecast, CI Seasonal Triangles for ",
                            Varname,
                            sep = ""),
           subtitle = str_c(region_name,
                            sep = "")) +
        
      xlab("Ensemble Standard Deviation") + 
      
      ylab("Root Mean Squared Error") +
      
      geom_point(data    = fx_subset,
                 color   = "grey",
                 alpha   = 0.5) +
      
      scale_colour_manual(values=c("DJF" = "cyan",
                                   "MAM" = "green",
                                   "JJA" = "magenta",
                                   "SON" = "orange"),
                        guide =FALSE) +
    
      geom_point(data    = seasonal_subset,
                 alpha   = 0.7)

      
    print(myplot)
    
  }

3b 500-hPa Heights


  Var     = "ISOHGT"
  Varname = "500-hPa Isobaric Heights"
  Hgt     = 500 * 100
  Fx      = 24

  for (Fx in Fx_Hour[2:length(Fx_Hour)]) {
    
    fx_subset = CI_Ensemble_Stats %>% filter((Variable == Var) &
                                             (Height   == Hgt) &
                                             (Fx_Hour  == Fx)  ) %>%
                                      select(-Quarter)
    
    seasonal_subset = CI_Ensemble_Stats %>% filter((Variable == Var) &
                                                   (Height   == Hgt) &
                                                   (Fx_Hour  == Fx)  )
    
    myplot = ggplot(data = seasonal_subset) +
      
      aes(x       = Ens_StDev,
          y       = RMSE_Ens000,
          color   = Quarter) + 
      
      facet_wrap(facets = ~ Quarter) + 
      
      theme_bw() +
      
      theme(strip.background = element_rect(fill=NA),
            ) +
      
      labs(title    = str_c(Fx,
                            "-hr Forecast, CI Seasonal Triangles for ",
                            Varname,
                            sep = ""),
           subtitle = str_c(region_name,
                            sep = "")) +
        
      xlab("Ensemble Standard Deviation") + 
      
      ylab("Root Mean Squared Error") +
      
      geom_point(data    = fx_subset,
                 color   = "grey",
                 alpha   = 0.5) +
      
      scale_colour_manual(values=c("DJF" = "cyan",
                                   "MAM" = "green",
                                   "JJA" = "magenta",
                                   "SON" = "orange"),
                        guide =FALSE) +
    
      geom_point(data    = seasonal_subset,
                 alpha   = 0.7)

      
    print(myplot)
    
  }

3c Mean Sea Level Pressure


  Var     = "MSLP"
  Varname = "Mean Sea Level Pressure"
  Hgt     = 0
  Fx      = 24

  for (Fx in Fx_Hour[2:length(Fx_Hour)]) {
    
    fx_subset = CI_Ensemble_Stats %>% filter((Variable == Var) &
                                             (Height   == Hgt) &
                                             (Fx_Hour  == Fx)  ) %>%
                                      select(-Quarter)
    
    seasonal_subset = CI_Ensemble_Stats %>% filter((Variable == Var) &
                                                   (Height   == Hgt) &
                                                   (Fx_Hour  == Fx)  )
    
    myplot = ggplot(data = seasonal_subset) +
      
      aes(x       = Ens_StDev,
          y       = RMSE_Ens000,
          color   = Quarter) + 
      
      facet_wrap(facets = ~ Quarter) + 
      
      theme_bw() +
      
      theme(strip.background = element_rect(fill=NA),
            ) +
      
      labs(title    = str_c(Fx,
                            "-hr Forecast, CI Seasonal Triangles for ",
                            Varname,
                            sep = ""),
           subtitle = str_c(region_name,
                            sep = "")) +
        
      xlab("Ensemble Standard Deviation") + 
      
      ylab("Root Mean Squared Error") +
      
      geom_point(data    = fx_subset,
                 color   = "grey",
                 alpha   = 0.5) +
      
      scale_colour_manual(values=c("DJF" = "cyan",
                                   "MAM" = "green",
                                   "JJA" = "magenta",
                                   "SON" = "orange"),
                        guide =FALSE) +
    
      geom_point(data    = seasonal_subset,
                 alpha   = 0.7)

      
    print(myplot)
    
  }

3d 10-m Wind Speeds


  Var     = "M10"
  Varname = "10-m Wind Speed"
  Hgt     = 10
  Fx      = 24

  for (Fx in Fx_Hour[2:length(Fx_Hour)]) {
    
    fx_subset = CI_Ensemble_Stats %>% filter((Variable == Var) &
                                             (Height   == Hgt) &
                                             (Fx_Hour  == Fx)  ) %>%
                                      select(-Quarter)
    
    seasonal_subset = CI_Ensemble_Stats %>% filter((Variable == Var) &
                                                   (Height   == Hgt) &
                                                   (Fx_Hour  == Fx)  )
    
    myplot = ggplot(data = seasonal_subset) +
      
      aes(x       = Ens_StDev,
          y       = RMSE_Ens000,
          color   = Quarter) + 
      
      facet_wrap(facets = ~ Quarter) + 
      
      theme_bw() +
      
      theme(strip.background = element_rect(fill=NA),
            ) +
      
      labs(title    = str_c(Fx,
                            "-hr Forecast, CI Seasonal Triangles for ",
                            Varname,
                            sep = ""),
           subtitle = str_c(region_name,
                            sep = "")) +
        
      xlab("Ensemble Standard Deviation") + 
      
      ylab("Root Mean Squared Error") +
      
      geom_point(data    = fx_subset,
                 color   = "grey",
                 alpha   = 0.5) +
      
      scale_colour_manual(values=c("DJF" = "cyan",
                                   "MAM" = "green",
                                   "JJA" = "magenta",
                                   "SON" = "orange"),
                        guide =FALSE) +
    
      geom_point(data    = seasonal_subset,
                 alpha   = 0.7)

      
    print(myplot)
    
  }

3e 10-m Wind Gusts


  Var     = "GUST"
  Varname = "10-m Wind Gusts"
  Hgt     = 10
  Fx      = 24

  for (Fx in Fx_Hour[2:length(Fx_Hour)]) {
    
    fx_subset = CI_Ensemble_Stats %>% filter((Variable == Var) &
                                             (Height   == Hgt) &
                                             (Fx_Hour  == Fx)  ) %>%
                                      select(-Quarter)
    
    seasonal_subset = CI_Ensemble_Stats %>% filter((Variable == Var) &
                                                   (Height   == Hgt) &
                                                   (Fx_Hour  == Fx)  )
    
    myplot = ggplot(data = seasonal_subset) +
      
      aes(x       = Ens_StDev,
          y       = RMSE_Ens000,
          color   = Quarter) + 
      
      facet_wrap(facets = ~ Quarter) + 
      
      theme_bw() +
      
      theme(strip.background = element_rect(fill=NA)) +
      
      labs(title    = str_c(Fx,
                            "-hr Forecast, CI Seasonal Triangles for ",
                            Varname,
                            sep = ""),
           subtitle = str_c(region_name,
                            sep = "")) +
        
      xlab("Ensemble Standard Deviation") + 
      
      ylab("Root Mean Squared Error") + 
      
      geom_point(data    = fx_subset,
                 color   = "grey",
                 alpha   = 0.5) +
      
      scale_colour_manual(values=c("DJF" = "cyan",
                                   "MAM" = "green",
                                   "JJA" = "magenta",
                                   "SON" = "orange"),
                        guide =FALSE) +
    
      geom_point(data    = seasonal_subset,
                 alpha   = 0.7)

      
    print(myplot)
    
  }

LS0tCnRpdGxlOiAiQ0kgRXh0ZW5kZWQgVHJpYW5nbGUgQW5hbHlzaXMiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCi0tLQoKIyAxIExpYnJhcmllcwoKYGBge3J9CgogIGxpYnJhcnkocGFja2FnZSA9ICJ0aWR5dmVyc2UiKQogIGxpYnJhcnkocGFja2FnZSA9ICJsdWJyaWRhdGUiKQoKICBsaWJyYXJ5KHBhY2thZ2UgPSAicmxpc3QiKQogIAogIGxpYnJhcnkocGFja2FnZSA9ICJuY2RmNCIpCiAgbGlicmFyeShwYWNrYWdlID0gIm5jZGY0LmhlbHBlcnMiKQogIAogIGxpYnJhcnkocGFja2FnZSA9ICJQQ0lDdCIpCiAgCiAgbGlicmFyeShwYWNrYWdlID0gInJlc2hhcGUyIikKYGBgCgojIDIgSW5wdXQgRGF0YSBGaWxlCgpgYGB7cn0KCiMgZGlyZWN0b3J5L1VSTCByb290CgogIGRpcmVjdG9yeSA9ICIvcHJvamVjdHMvQklHX1dFQVRIRVIvR0VOU19FUlJPUl9SVC90cmlhbmdsZV9hcmNoaXZlcy8iCiAgZGlyZWN0b3J5ID0gImh0dHA6Ly9reXJpbGwuaWFzLnNkc210LmVkdTo4MDgwL3RocmVkZHMvZmlsZVNlcnZlci9CV1dfR0VOUy9DSV9TVEFULyIKCiAgdGltZV9yYW5nZSA9ICIyMDE1LTA2LTAxXzAwX3RvXzIwMTktMDMtMzFfMDAiCiAgCiAgcmVnaW9uID0gIldSRlJBUCIKICAKICBSZGF0YUZpbGUgPSBzdHJfYyhkaXJlY3RvcnksCiAgICAgICAgICAgICAgICAgICJnZW5zXzAzX2Vuc2VtYmxlX18iLAogICAgICAgICAgICAgICAgICAiVDJNX01TTFBfTTEwX1NQQ0gyTV9JU09IR1RfVTEwX1YxMF9GUklDVl9HVVNUIiwKICAgICAgICAgICAgICAgICAgIl9fZXJyb3JfXyIsCiAgICAgICAgICAgICAgICAgIHJlZ2lvbiwKICAgICAgICAgICAgICAgICAgIl9fIiwKICAgICAgICAgICAgICAgICAgdGltZV9yYW5nZSwKICAgICAgICAgICAgICAgICAgIi5SRGF0YSIsCiAgICAgICAgICAgICAgICAgIHNlcCA9ICIiKQoKICBsb2FkKGZpbGUgPSB1cmwoUmRhdGFGaWxlKSkgCiAgCiAgVGltZSAgICAgPSB1bmlxdWUoQ0lfRW5zZW1ibGVfU3RhdHMkVGltZSkKICBGeF9Ib3VyICA9IHVuaXF1ZShDSV9FbnNlbWJsZV9TdGF0cyRGeF9Ib3VyKQogIFZhcmlhYmxlID0gdW5pcXVlKENJX0Vuc2VtYmxlX1N0YXRzJFZhcmlhYmxlKQogIEhlaWdodCAgID0gdW5pcXVlKENJX0Vuc2VtYmxlX1N0YXRzJEhlaWdodCkKICAKICBDSV9FbnNlbWJsZV9TdGF0cyRNb250aCAgID0gbW9udGgoQ0lfRW5zZW1ibGVfU3RhdHMkVGltZSkKCiAgQ0lfRW5zZW1ibGVfU3RhdHMgPSBDSV9FbnNlbWJsZV9TdGF0cyAlPiUgCiAgICBtdXRhdGUoUXVhcnRlciA9IGNhc2Vfd2hlbigoKE1vbnRoID09IDEyKSB8IChNb250aCA9PSAwMSkgfCAoTW9udGggPT0gMDIpKSAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+ICJESkYiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChNb250aCA9PSAwMykgfCAoTW9udGggPT0gMDQpIHwgKE1vbnRoID09IDA1KSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH4gIk1BTSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKE1vbnRoID09IDA2KSB8IChNb250aCA9PSAwNykgfCAoTW9udGggPT0gMDgpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfiAiSkpBIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoTW9udGggPT0gMDkpIHwgKE1vbnRoID09IDEwKSB8IChNb250aCA9PSAxMSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB+ICJTT04iKSApCgpgYGAKCiMgMyBUcmlhbmdsZSBQbG90cwoKIyMgM2EgMi1tIEFpciBUZW1wZXJhdHVyZQoKYGBge3J9CgogIFZhciAgICAgPSAiVDJNIgogIFZhcm5hbWUgPSAiMi1tIEFpciBUZW1wZXJhdHVyZSIKICBIZ3QgICAgID0gMgogIEZ4ICAgICAgPSAyNAoKICBmb3IgKEZ4IGluIEZ4X0hvdXJbMjpsZW5ndGgoRnhfSG91cildKSB7CiAgICAKICAgIGZ4X3N1YnNldCA9IENJX0Vuc2VtYmxlX1N0YXRzICU+JSBmaWx0ZXIoKFZhcmlhYmxlID09IFZhcikgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSGVpZ2h0ICAgPT0gSGd0KSAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChGeF9Ib3VyICA9PSBGeCkgICkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KC1RdWFydGVyKQogICAgCiAgICBzZWFzb25hbF9zdWJzZXQgPSBDSV9FbnNlbWJsZV9TdGF0cyAlPiUgZmlsdGVyKChWYXJpYWJsZSA9PSBWYXIpICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEhlaWdodCAgID09IEhndCkgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoRnhfSG91ciAgPT0gRngpICApCiAgICAKICAgIG15cGxvdCA9IGdncGxvdChkYXRhID0gc2Vhc29uYWxfc3Vic2V0KSArCiAgICAgIAogICAgICBhZXMoeCAgICAgICA9IEVuc19TdERldiwKICAgICAgICAgIHkgICAgICAgPSBSTVNFX0VuczAwMCwKICAgICAgICAgIGNvbG9yICAgPSBRdWFydGVyKSArIAogICAgICAKICAgICAgZmFjZXRfd3JhcChmYWNldHMgPSB+IFF1YXJ0ZXIpICsgCiAgICAgIAogICAgICB0aGVtZV9idygpICsKICAgICAgCiAgICAgIHRoZW1lKHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD1OQSksCiAgICAgICAgICAgICkgKwogICAgICAKICAgICAgbGFicyh0aXRsZSAgICA9IHN0cl9jKEZ4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIi1ociBGb3JlY2FzdCwgQ0kgU2Vhc29uYWwgVHJpYW5nbGVzIGZvciAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFybmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICIiKSwKICAgICAgICAgICBzdWJ0aXRsZSA9IHN0cl9jKHJlZ2lvbl9uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VwID0gIiIpKSArCiAgICAgICAgCiAgICAgIHhsYWIoIkVuc2VtYmxlIFN0YW5kYXJkIERldmlhdGlvbiIpICsgCiAgICAgIAogICAgICB5bGFiKCJSb290IE1lYW4gU3F1YXJlZCBFcnJvciIpICsKICAgICAgCiAgICAgIGdlb21fcG9pbnQoZGF0YSAgICA9IGZ4X3N1YnNldCwKICAgICAgICAgICAgICAgICBjb2xvciAgID0gImdyZXkiLAogICAgICAgICAgICAgICAgIGFscGhhICAgPSAwLjUpICsKICAgICAgCiAgICAgIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPWMoIkRKRiIgPSAiY3lhbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1BTSIgPSAiZ3JlZW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJKSkEiID0gIm1hZ2VudGEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTT04iID0gIm9yYW5nZSIpLAogICAgICAgICAgICAgICAgICAgICAgICBndWlkZSA9RkFMU0UpICsKICAgIAogICAgICBnZW9tX3BvaW50KGRhdGEgICAgPSBzZWFzb25hbF9zdWJzZXQsCiAgICAgICAgICAgICAgICAgYWxwaGEgICA9IDAuNykKCiAgICAgIAogICAgcHJpbnQobXlwbG90KQogICAgCiAgfQoKYGBgCgojIyAzYiA1MDAtaFBhIEhlaWdodHMKCmBgYHtyfQoKICBWYXIgICAgID0gIklTT0hHVCIKICBWYXJuYW1lID0gIjUwMC1oUGEgSXNvYmFyaWMgSGVpZ2h0cyIKICBIZ3QgICAgID0gNTAwICogMTAwCiAgRnggICAgICA9IDI0CgogIGZvciAoRnggaW4gRnhfSG91clsyOmxlbmd0aChGeF9Ib3VyKV0pIHsKICAgIAogICAgZnhfc3Vic2V0ID0gQ0lfRW5zZW1ibGVfU3RhdHMgJT4lIGZpbHRlcigoVmFyaWFibGUgPT0gVmFyKSAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChIZWlnaHQgICA9PSBIZ3QpICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEZ4X0hvdXIgID09IEZ4KSAgKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QoLVF1YXJ0ZXIpCiAgICAKICAgIHNlYXNvbmFsX3N1YnNldCA9IENJX0Vuc2VtYmxlX1N0YXRzICU+JSBmaWx0ZXIoKFZhcmlhYmxlID09IFZhcikgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSGVpZ2h0ICAgPT0gSGd0KSAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChGeF9Ib3VyICA9PSBGeCkgICkKICAgIAogICAgbXlwbG90ID0gZ2dwbG90KGRhdGEgPSBzZWFzb25hbF9zdWJzZXQpICsKICAgICAgCiAgICAgIGFlcyh4ICAgICAgID0gRW5zX1N0RGV2LAogICAgICAgICAgeSAgICAgICA9IFJNU0VfRW5zMDAwLAogICAgICAgICAgY29sb3IgICA9IFF1YXJ0ZXIpICsgCiAgICAgIAogICAgICBmYWNldF93cmFwKGZhY2V0cyA9IH4gUXVhcnRlcikgKyAKICAgICAgCiAgICAgIHRoZW1lX2J3KCkgKwogICAgICAKICAgICAgdGhlbWUoc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPU5BKSwKICAgICAgICAgICAgKSArCiAgICAgIAogICAgICBsYWJzKHRpdGxlICAgID0gc3RyX2MoRngsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLWhyIEZvcmVjYXN0LCBDSSBTZWFzb25hbCBUcmlhbmdsZXMgZm9yICIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYXJuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VwID0gIiIpLAogICAgICAgICAgIHN1YnRpdGxlID0gc3RyX2MocmVnaW9uX25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXAgPSAiIikpICsKICAgICAgICAKICAgICAgeGxhYigiRW5zZW1ibGUgU3RhbmRhcmQgRGV2aWF0aW9uIikgKyAKICAgICAgCiAgICAgIHlsYWIoIlJvb3QgTWVhbiBTcXVhcmVkIEVycm9yIikgKwogICAgICAKICAgICAgZ2VvbV9wb2ludChkYXRhICAgID0gZnhfc3Vic2V0LAogICAgICAgICAgICAgICAgIGNvbG9yICAgPSAiZ3JleSIsCiAgICAgICAgICAgICAgICAgYWxwaGEgICA9IDAuNSkgKwogICAgICAKICAgICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9YygiREpGIiA9ICJjeWFuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTUFNIiA9ICJncmVlbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkpKQSIgPSAibWFnZW50YSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNPTiIgPSAib3JhbmdlIiksCiAgICAgICAgICAgICAgICAgICAgICAgIGd1aWRlID1GQUxTRSkgKwogICAgCiAgICAgIGdlb21fcG9pbnQoZGF0YSAgICA9IHNlYXNvbmFsX3N1YnNldCwKICAgICAgICAgICAgICAgICBhbHBoYSAgID0gMC43KQoKICAgICAgCiAgICBwcmludChteXBsb3QpCiAgICAKICB9CgpgYGAKCiMjIDNjIE1lYW4gU2VhIExldmVsIFByZXNzdXJlCgpgYGB7cn0KCiAgVmFyICAgICA9ICJNU0xQIgogIFZhcm5hbWUgPSAiTWVhbiBTZWEgTGV2ZWwgUHJlc3N1cmUiCiAgSGd0ICAgICA9IDAKICBGeCAgICAgID0gMjQKCiAgZm9yIChGeCBpbiBGeF9Ib3VyWzI6bGVuZ3RoKEZ4X0hvdXIpXSkgewogICAgCiAgICBmeF9zdWJzZXQgPSBDSV9FbnNlbWJsZV9TdGF0cyAlPiUgZmlsdGVyKChWYXJpYWJsZSA9PSBWYXIpICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEhlaWdodCAgID09IEhndCkgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoRnhfSG91ciAgPT0gRngpICApICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdCgtUXVhcnRlcikKICAgIAogICAgc2Vhc29uYWxfc3Vic2V0ID0gQ0lfRW5zZW1ibGVfU3RhdHMgJT4lIGZpbHRlcigoVmFyaWFibGUgPT0gVmFyKSAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChIZWlnaHQgICA9PSBIZ3QpICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEZ4X0hvdXIgID09IEZ4KSAgKQogICAgCiAgICBteXBsb3QgPSBnZ3Bsb3QoZGF0YSA9IHNlYXNvbmFsX3N1YnNldCkgKwogICAgICAKICAgICAgYWVzKHggICAgICAgPSBFbnNfU3REZXYsCiAgICAgICAgICB5ICAgICAgID0gUk1TRV9FbnMwMDAsCiAgICAgICAgICBjb2xvciAgID0gUXVhcnRlcikgKyAKICAgICAgCiAgICAgIGZhY2V0X3dyYXAoZmFjZXRzID0gfiBRdWFydGVyKSArIAogICAgICAKICAgICAgdGhlbWVfYncoKSArCiAgICAgIAogICAgICB0aGVtZShzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9TkEpLAogICAgICAgICAgICApICsKICAgICAgCiAgICAgIGxhYnModGl0bGUgICAgPSBzdHJfYyhGeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICItaHIgRm9yZWNhc3QsIENJIFNlYXNvbmFsIFRyaWFuZ2xlcyBmb3IgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhcm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXAgPSAiIiksCiAgICAgICAgICAgc3VidGl0bGUgPSBzdHJfYyhyZWdpb25fbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICIiKSkgKwogICAgICAgIAogICAgICB4bGFiKCJFbnNlbWJsZSBTdGFuZGFyZCBEZXZpYXRpb24iKSArIAogICAgICAKICAgICAgeWxhYigiUm9vdCBNZWFuIFNxdWFyZWQgRXJyb3IiKSArCiAgICAgIAogICAgICBnZW9tX3BvaW50KGRhdGEgICAgPSBmeF9zdWJzZXQsCiAgICAgICAgICAgICAgICAgY29sb3IgICA9ICJncmV5IiwKICAgICAgICAgICAgICAgICBhbHBoYSAgID0gMC41KSArCiAgICAgIAogICAgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1jKCJESkYiID0gImN5YW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNQU0iID0gImdyZWVuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiSkpBIiA9ICJtYWdlbnRhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU09OIiA9ICJvcmFuZ2UiKSwKICAgICAgICAgICAgICAgICAgICAgICAgZ3VpZGUgPUZBTFNFKSArCiAgICAKICAgICAgZ2VvbV9wb2ludChkYXRhICAgID0gc2Vhc29uYWxfc3Vic2V0LAogICAgICAgICAgICAgICAgIGFscGhhICAgPSAwLjcpCgogICAgICAKICAgIHByaW50KG15cGxvdCkKICAgIAogIH0KCmBgYAoKIyMgM2QgMTAtbSBXaW5kIFNwZWVkcwoKYGBge3J9CgogIFZhciAgICAgPSAiTTEwIgogIFZhcm5hbWUgPSAiMTAtbSBXaW5kIFNwZWVkIgogIEhndCAgICAgPSAxMAogIEZ4ICAgICAgPSAyNAoKICBmb3IgKEZ4IGluIEZ4X0hvdXJbMjpsZW5ndGgoRnhfSG91cildKSB7CiAgICAKICAgIGZ4X3N1YnNldCA9IENJX0Vuc2VtYmxlX1N0YXRzICU+JSBmaWx0ZXIoKFZhcmlhYmxlID09IFZhcikgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSGVpZ2h0ICAgPT0gSGd0KSAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChGeF9Ib3VyICA9PSBGeCkgICkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KC1RdWFydGVyKQogICAgCiAgICBzZWFzb25hbF9zdWJzZXQgPSBDSV9FbnNlbWJsZV9TdGF0cyAlPiUgZmlsdGVyKChWYXJpYWJsZSA9PSBWYXIpICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEhlaWdodCAgID09IEhndCkgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoRnhfSG91ciAgPT0gRngpICApCiAgICAKICAgIG15cGxvdCA9IGdncGxvdChkYXRhID0gc2Vhc29uYWxfc3Vic2V0KSArCiAgICAgIAogICAgICBhZXMoeCAgICAgICA9IEVuc19TdERldiwKICAgICAgICAgIHkgICAgICAgPSBSTVNFX0VuczAwMCwKICAgICAgICAgIGNvbG9yICAgPSBRdWFydGVyKSArIAogICAgICAKICAgICAgZmFjZXRfd3JhcChmYWNldHMgPSB+IFF1YXJ0ZXIpICsgCiAgICAgIAogICAgICB0aGVtZV9idygpICsKICAgICAgCiAgICAgIHRoZW1lKHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD1OQSksCiAgICAgICAgICAgICkgKwogICAgICAKICAgICAgbGFicyh0aXRsZSAgICA9IHN0cl9jKEZ4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIi1ociBGb3JlY2FzdCwgQ0kgU2Vhc29uYWwgVHJpYW5nbGVzIGZvciAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFybmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICIiKSwKICAgICAgICAgICBzdWJ0aXRsZSA9IHN0cl9jKHJlZ2lvbl9uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VwID0gIiIpKSArCiAgICAgICAgCiAgICAgIHhsYWIoIkVuc2VtYmxlIFN0YW5kYXJkIERldmlhdGlvbiIpICsgCiAgICAgIAogICAgICB5bGFiKCJSb290IE1lYW4gU3F1YXJlZCBFcnJvciIpICsKICAgICAgCiAgICAgIGdlb21fcG9pbnQoZGF0YSAgICA9IGZ4X3N1YnNldCwKICAgICAgICAgICAgICAgICBjb2xvciAgID0gImdyZXkiLAogICAgICAgICAgICAgICAgIGFscGhhICAgPSAwLjUpICsKICAgICAgCiAgICAgIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPWMoIkRKRiIgPSAiY3lhbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1BTSIgPSAiZ3JlZW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJKSkEiID0gIm1hZ2VudGEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTT04iID0gIm9yYW5nZSIpLAogICAgICAgICAgICAgICAgICAgICAgICBndWlkZSA9RkFMU0UpICsKICAgIAogICAgICBnZW9tX3BvaW50KGRhdGEgICAgPSBzZWFzb25hbF9zdWJzZXQsCiAgICAgICAgICAgICAgICAgYWxwaGEgICA9IDAuNykKCiAgICAgIAogICAgcHJpbnQobXlwbG90KQogICAgCiAgfQoKYGBgCgoKIyMgM2UgMTAtbSBXaW5kIEd1c3RzCgpgYGB7cn0KCiAgVmFyICAgICA9ICJHVVNUIgogIFZhcm5hbWUgPSAiMTAtbSBXaW5kIEd1c3RzIgogIEhndCAgICAgPSAxMAogIEZ4ICAgICAgPSAyNAoKICBmb3IgKEZ4IGluIEZ4X0hvdXJbMjpsZW5ndGgoRnhfSG91cildKSB7CiAgICAKICAgIGZ4X3N1YnNldCA9IENJX0Vuc2VtYmxlX1N0YXRzICU+JSBmaWx0ZXIoKFZhcmlhYmxlID09IFZhcikgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSGVpZ2h0ICAgPT0gSGd0KSAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChGeF9Ib3VyICA9PSBGeCkgICkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KC1RdWFydGVyKQogICAgCiAgICBzZWFzb25hbF9zdWJzZXQgPSBDSV9FbnNlbWJsZV9TdGF0cyAlPiUgZmlsdGVyKChWYXJpYWJsZSA9PSBWYXIpICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEhlaWdodCAgID09IEhndCkgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoRnhfSG91ciAgPT0gRngpICApCiAgICAKICAgIG15cGxvdCA9IGdncGxvdChkYXRhID0gc2Vhc29uYWxfc3Vic2V0KSArCiAgICAgIAogICAgICBhZXMoeCAgICAgICA9IEVuc19TdERldiwKICAgICAgICAgIHkgICAgICAgPSBSTVNFX0VuczAwMCwKICAgICAgICAgIGNvbG9yICAgPSBRdWFydGVyKSArIAogICAgICAKICAgICAgZmFjZXRfd3JhcChmYWNldHMgPSB+IFF1YXJ0ZXIpICsgCiAgICAgIAogICAgICB0aGVtZV9idygpICsKICAgICAgCiAgICAgIHRoZW1lKHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD1OQSkpICsKICAgICAgCiAgICAgIGxhYnModGl0bGUgICAgPSBzdHJfYyhGeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICItaHIgRm9yZWNhc3QsIENJIFNlYXNvbmFsIFRyaWFuZ2xlcyBmb3IgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZhcm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXAgPSAiIiksCiAgICAgICAgICAgc3VidGl0bGUgPSBzdHJfYyhyZWdpb25fbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlcCA9ICIiKSkgKwogICAgICAgIAogICAgICB4bGFiKCJFbnNlbWJsZSBTdGFuZGFyZCBEZXZpYXRpb24iKSArIAogICAgICAKICAgICAgeWxhYigiUm9vdCBNZWFuIFNxdWFyZWQgRXJyb3IiKSArIAogICAgICAKICAgICAgZ2VvbV9wb2ludChkYXRhICAgID0gZnhfc3Vic2V0LAogICAgICAgICAgICAgICAgIGNvbG9yICAgPSAiZ3JleSIsCiAgICAgICAgICAgICAgICAgYWxwaGEgICA9IDAuNSkgKwogICAgICAKICAgICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9YygiREpGIiA9ICJjeWFuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTUFNIiA9ICJncmVlbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkpKQSIgPSAibWFnZW50YSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNPTiIgPSAib3JhbmdlIiksCiAgICAgICAgICAgICAgICAgICAgICAgIGd1aWRlID1GQUxTRSkgKwogICAgCiAgICAgIGdlb21fcG9pbnQoZGF0YSAgICA9IHNlYXNvbmFsX3N1YnNldCwKICAgICAgICAgICAgICAgICBhbHBoYSAgID0gMC43KQoKICAgICAgCiAgICBwcmludChteXBsb3QpCiAgICAKICB9CgpgYGAKCg==